package com.evl.api.trainOrder.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.evl.api.qrcode.service.IWeiXinService;
import com.evl.api.qrcode.vo.TemplateRQ;
import com.evl.api.trainOrder.service.IApiTrainOrderService;
import com.evl.api.trainOrder.vo.PassengerRQ;
import com.evl.api.trainOrder.vo.PassengerRS;
import com.evl.api.trainOrder.vo.TrainOrderCreateRQ;
import com.evl.api.trainOrder.vo.TrainOrderSearchRQ;
import com.evl.api.trainOrder.vo.TrainOrderSearchRS;
import com.evl.api.trainOrder.vo.TrainTicketSearchRQ;
import com.evl.common.constant.Const;
import com.evl.common.constant.OrderConst;
import com.evl.common.persistence.dao.OrderRecordMapper;
import com.evl.common.persistence.dao.RefundOrderMapper;
import com.evl.common.persistence.dao.TrainOrderMapper;
import com.evl.common.persistence.dao.TrainTicketMapper;
import com.evl.common.persistence.model.OrderRecord;
import com.evl.common.persistence.model.RefundOrder;
import com.evl.common.persistence.model.RefundRule;
import com.evl.common.persistence.model.ScheduleStation;
import com.evl.common.persistence.model.StationSeatR;
import com.evl.common.persistence.model.TrainOrder;
import com.evl.common.persistence.model.TrainTicket;
import com.evl.constant.ErrorContant;
import com.evl.constant.TicketType;
import com.evl.constant.TrainTicketStatus;
import com.evl.core.util.ToolUtil;
import com.evl.core.vo.BaseResultVo;
import com.evl.core.vo.JsonReturnHelper;
import com.evl.dictionaryConfig.DictConfig;
import com.evl.dictionaryConfig.DictConst;
import com.evl.refundRule.service.IRefundRuleService;
import com.evl.trainOrder.service.ITrainOrderService;
import com.evl.trainSeat.service.ITrainSeatService;
import com.evl.utils.BeanUtils;
import com.evl.utils.DateUtils;
import com.evl.utils.ObjectUtil;
import com.evl.utils.filter.Filter;
import com.evl.utils.filter.ListFilter;
import com.evl.wxpay.util.paytype.PayType;
import com.evl.wxpay.util.paytype.WxPayApi;
import com.google.gson.JsonObject;

@Service
public class ApiTrainOrderServiceImpl implements IApiTrainOrderService {

	@Resource
	private TrainTicketMapper trainTicketMapper;

	@Resource
	private ITrainSeatService trainSeatService;

	@Resource
	private ITrainOrderService trainOrderService;

	@Resource
	private TrainOrderMapper orderMapper;

	@Resource
	private OrderRecordMapper recordMapper;

	@Resource
	private RefundOrderMapper refundOrderMapper;
	
	@Resource
	private IRefundRuleService 	iRefundRuleService;
	
	@Resource
	private IWeiXinService iWeiXinService;

	@Override
	@Transactional
	public TrainOrder trainOrder(TrainOrderCreateRQ trainOrderRq) throws Exception {
		// 选座，占座
		BaseResultVo resoutVo = trainSeatService.queryStationSeat(trainOrderRq);
		if (!StringUtils.isEmpty(resoutVo.getErrorCode())) {
			throw new Exception(resoutVo.getErrorMessage());
		}
		trainOrderRq = (TrainOrderCreateRQ) resoutVo.getData();
		// 设置订单号
		try {
			trainOrderRq.setOrderNo(ToolUtil.getOrderNo(TicketType.QH));
		} catch (Exception e) {
			throw new Exception(ErrorContant.TICKET_STATUS_TRAIN_ORDER_NO_ERROR_MSG);
		}

		// 设置支付状态为未支付
		trainOrderRq.setOrderStatus(OrderConst.STS_NOPAYED);

		// 保存主订单数据
		TrainOrder trainOrder = ObjectUtil.concat(new TrainOrder(), trainOrderRq);
		trainOrderService.addTrainOrder(trainOrder);

		// 保存座位信息
		List<PassengerRQ> passers = trainOrderRq.getUserList();
		List<TrainTicket> trainTickets = new ArrayList<TrainTicket>();
		for (PassengerRQ passer : passers) {
			TrainTicket trainTicket = new TrainTicket();
			trainTicket.setOrderId(trainOrder.getId());
			trainTicket.setContactId(passer.getId());
			trainTicket.setSeatId(passer.getSeatId());
			trainTicket.setSeatNo(passer.getSeatNo());
			trainTicket.setSeatType(passer.getSeatType());
			trainTicket.setStatus(Const.TRAIN_TICKET_LOCKED + ""); // 已锁定车票
			trainTicket.setTicketType(passer.getTicketType());
			trainTicket.setPrice(passer.getPrice());
			trainTickets.add(trainTicket);
		}
		trainTicketMapper.insertList(trainTickets);
		return trainOrder;
	}

	@Override
	public List<TrainOrderSearchRS> searchTrainOrder(TrainOrderSearchRQ rq) {
		return orderMapper.findTrainOrders(rq);
	}

	@Override
	@Transactional
	public BaseResultVo refundTicket(String ticketId) {

		TrainTicket trainTicket = trainTicketMapper.selectById(ticketId);
		RefundOrder refundOrder = refundOrderMapper.selectByTicketId(ticketId + "");
		TrainOrder trainOrder = orderMapper.selectById(trainTicket.getOrderId());
		/*********** 3.调用微信退款接口 ************************/
		try {
			Map refundMap = WxPayApi.Instance().request(refundOrder, PayType.REFUND);
			String return_code = refundMap.get("return_code").toString();
			if (!return_code.equals("SUCCESS")) {
				return JsonReturnHelper.getFailWithError(ErrorContant.REFUND_ORDER_PAY_ERROR_MSG,
						ErrorContant.REFUND_ORDER_PAY_ERROR_CODE);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
			return JsonReturnHelper.getFailWithError(ErrorContant.REFUND_ORDER_PAY_ERROR_MSG,
					ErrorContant.REFUND_ORDER_PAY_ERROR_CODE);
		}

		/*********** 4.修改车票状态 ************************/
		try {
			trainTicket.setStatus(String.valueOf(Const.TRAIN_TICKET_REFUND));
			trainTicketMapper.updateById(trainTicket);
		} catch (Exception e) {
			return JsonReturnHelper.getFailWithError(ErrorContant.TRAIN_TICKET_UPDATESTATUS_MSG,
					ErrorContant.TRAIN_TICKET_UPDATESTATUS_CODE);
		}

		/*********** 5.修改车票座位状态为可选 ************************/
		List<StationSeatR> seatList = new ArrayList<StationSeatR>();
		try {
			List<ScheduleStation> stations = trainSeatService.getStationLine(trainOrder.getStaId() + "",
					trainOrder.getDeparture(), trainOrder.getArrive());

			for (ScheduleStation st : stations) {
				StationSeatR r = new StationSeatR();
				r.setSeatId(trainTicket.getSeatId());
				r.setStationId(st.getId());
				r.setSeatStatus(Const.SEAT_CHOOSABLE);
				seatList.add(r);
			}

			trainSeatService.releaseStationSeatR(seatList);

		} catch (Exception e) {
			return JsonReturnHelper.getFailWithError(ErrorContant.TICKET_REMAINDER_RELEASE_MSG,
					ErrorContant.TICKET_REMAINDER_RELEASE_CODE);
		}

		/*********** 6.生成订单流水 *************************/
		OrderRecord record = new OrderRecord();
		record.setContent("退票");
		record.setCreateTime(new Date());
		record.setType(String.valueOf(trainOrder.getOrderType()));
		record.setRecordNo(trainOrder.getTrainNo());
		recordMapper.insert(record);

		return JsonReturnHelper.getSuccessWithData(refundOrder);
	}

	@Override
	public BaseResultVo invailOrder(String orderId) {
		TrainOrder trainOrder = orderMapper.selectById(orderId);
		List<TrainOrder> list = new ArrayList<>();
		list.add(trainOrder);
		try {
			trainOrderService.invaliOrderList(list);
		} catch (Exception e) {
			e.printStackTrace();
			return JsonReturnHelper.getFailWithError(e.getMessage(), "");
		}
		return JsonReturnHelper.getSuccessWithNull();
	}

	@Override
	@Transactional
	public BaseResultVo refundTicketApply(TrainTicketSearchRQ paramVo) {
		
		TrainTicket trainTicket = trainTicketMapper.selectById(paramVo.getTicketId());
		TrainOrder trainOrder = orderMapper.selectById(trainTicket.getOrderId());
		/*********** 2.生成退款单 ************************/
		RefundOrder refundOrder = refundOrderMapper.selectByTicketId(trainTicket.getId() + "");
		if (null == refundOrder) {// 第一次退款
			refundOrder = new RefundOrder();
			RefundRule fundRule = iRefundRuleService.selectfundRule(trainOrder.getDepTime());
			Double ratio = 0.0;
			if(fundRule != null){
				ratio = fundRule.getRefundRatio();
			}
			;
			try {
				refundOrder.setRefundNo(ToolUtil.getOrderNo(TicketType.TP));
				refundOrder.setOpenid(trainOrder.getCreateId());
				refundOrder.setOrderNo(trainOrder.getOrderNo());
				refundOrder.setOrderId(trainOrder.getId() + "");
				refundOrder.setOldPrice(Double.parseDouble(trainTicket.getPrice())); //订单原金额
				refundOrder.setRefundPrice(Double.parseDouble(trainTicket.getPrice())*ratio);	//实际退款金额
				refundOrder.setRefundRadio(ratio);	//退款比例
				refundOrder.setApplyTime(new Date());
				refundOrder.setTicketId(trainTicket.getId());
				refundOrder.setStatus(OrderConst.REFUND_ORDER_STATUS_WAIT);
				refundOrderMapper.insertSelective(refundOrder);
				//更新车票状态，新建vo更新指定参数
				TrainTicket updatetrainTicket = new TrainTicket();
				updatetrainTicket.setId(paramVo.getTicketId());
				updatetrainTicket.setStatus(String.valueOf(Const.TRAIN_TICKET_REFUNDING));
				trainTicketMapper.updateById(updatetrainTicket);
			} catch (Exception e1) {
				e1.printStackTrace();
				return JsonReturnHelper.getFailWithError(ErrorContant.REFUND_ORDER_CREATE_ERROR_MSG,
						ErrorContant.REFUND_ORDER_CREATE_ERROR_CODE);
			}
			//推送微信消息
			//sendMessage(refundOrder,paramVo);
			//不经过审核直接退费
			this.refundTicket(paramVo.getTicketId()+"");
		} else {
			// 重复退款
			if (refundOrder.getStatus().equals(OrderConst.REFUND_ORDER_STATUS_END)) {
				return JsonReturnHelper.getFailWithError(ErrorContant.REFUND_ORDER_PAY_DOUBLE_MSG,
						ErrorContant.REFUND_ORDER_PAY_DOUBLE_CODE);
			}
		}
		return JsonReturnHelper.getSuccessWithData(refundOrder);
	}
	
	public void sendMessage(RefundOrder refundOrder,TrainTicketSearchRQ paramVo) {
		if(StringUtils.isEmpty(paramVo.getFormId())){
			return;
		}
    	String page= DictConfig.getKey(DictConst.wx_msg_index_page);
    	String template_id = DictConfig.getKey(DictConst.wx_refund_apply_sucess_msg_temp);
    	JsonObject jsonObject=new JsonObject();
    		
    	JsonObject key1=new JsonObject();
		key1.addProperty("value", refundOrder.getOrderNo());
		jsonObject.add("keyword1", key1);
		
		JsonObject key2=new JsonObject();
		key2.addProperty("value", refundOrder.getRefundNo());
		jsonObject.add("keyword2", key2);
		
		JsonObject key3=new JsonObject();
		key3.addProperty("value", DateUtils.getSpecifyDate(refundOrder.getApplyTime(),DateUtils.FORMAT_YYYY_MM_DD_HH_MM_SS));
		jsonObject.add("keyword3", key3);
		
		JsonObject key4=new JsonObject();
		key4.addProperty("value", refundOrder.getRefundPrice().toString());
		jsonObject.add("keyword4", key4);
		
		JsonObject key5=new JsonObject();
		key5.addProperty("value", "车票退款申请");
		jsonObject.add("keyword5", key5);
		
    	
    	TemplateRQ templateRQ=new TemplateRQ();
    	templateRQ.setTouser(paramVo.getOpendId());
    	templateRQ.setTemplate_id(template_id);
    	templateRQ.setPage(page);
    	templateRQ.setData(jsonObject);
    	templateRQ.setForm_id(paramVo.getFormId());
    	iWeiXinService.sendTemplate(templateRQ);
	}

	@Override
	public BaseResultVo searchOrderTicket(TrainOrderSearchRQ rq) {
		List<TrainOrderSearchRS> list = searchTrainOrder(rq);
    	if(list.isEmpty()){
    		return JsonReturnHelper.getSuccessWithData(null);
    	}
    	
    	final TrainOrderSearchRS tsrs = list.get(0);
    	final List<String> ticketIds = rq.getTicketIds();
    	tsrs.setUserList(ObjectUtil.filterList(tsrs.getUserList(), new ListFilter<PassengerRS>() {
			@Override
			public PassengerRS filterElement(PassengerRS o) {
				o.setStatus(TrainTicketStatus.valueOf(Integer.parseInt(String.valueOf(o.getStatus()))));
				//增加退票费率信息
				RefundRule fundRule = iRefundRuleService.selectfundRule(tsrs.getDepTime());
				if(null == fundRule){
					o.setRefundPrice("-1");
					o.setRefundPriceRatio("0");
				}else{
					Double ratio = fundRule.getRefundRatio();
					Double refundPrice = Double.parseDouble(o.getPrice())*ratio;
					o.setRefundPrice(refundPrice.toString());
					o.setRefundPriceRatio(ratio.toString());
				}
				return o;
			}
			
			@SuppressWarnings("null")
			@Override
			public boolean isRemove(PassengerRS o) {
				if((null == ticketIds || ticketIds.size() == 0)
						|| (ticketIds.contains(o.getTicketId()))){
					return false;
				}
				return true;
			}
		}));
    	
    	return JsonReturnHelper.getSuccessWithData(tsrs);
	}
}
